package com.pentofab.payrollmanagement.ui.controller;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.ResourceBundle;

import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.Parent;
import javafx.scene.control.CheckBox;
import javafx.scene.control.ChoiceBox;
import javafx.scene.control.TextField;
import javafx.scene.layout.GridPane;
import javafx.stage.FileChooser;

import com.pentofab.payrollmanagement.application.PayrollApplicationFactory;
import com.pentofab.payrollmanagement.dao.EmployeeDao;
import com.pentofab.payrollmanagement.dao.SalaryDAO;
import com.pentofab.payrollmanagement.dao.model.BankInfo;
import com.pentofab.payrollmanagement.dao.model.Company;
import com.pentofab.payrollmanagement.dao.model.Employee;
import com.pentofab.payrollmanagement.dao.model.SalaryProfile;
import com.pentofab.payrollmanagement.dao.model.SalaryStracture;
import com.pentofab.payrollmanagement.dao.model.Units;
import com.pentofab.payrollmanagement.dao.model.UserAccounts;
import com.pentofab.payrollmanagement.exception.BusinessException;
import com.pentofab.payrollmanagement.ui.control.CustomTextField;
import com.pentofab.payrollmanagement.utilities.PayRollUtility;

public class SalaryStractureController extends AbstractUIController implements
FormValidator {
	
	
	@FXML
	private CustomTextField basicPer;
	@FXML
	private CustomTextField conveyance;
	@FXML
	private CustomTextField grossSalary;
	@FXML
	private CustomTextField hra;
	@FXML
	private CustomTextField medicalAllowance;
	@FXML
	private TextField specialAllowance;
	@FXML
	private CustomTextField others;
	@FXML 
    private TextField company;
	@FXML
    private TextField departMent;
	@FXML
    private TextField emloyeerCont;
	@FXML
    private TextField empId;
	@FXML
    private TextField empName;
	@FXML
    private TextField employeeCont;
	@FXML
    private TextField esiNumber;
    @FXML
    private CheckBox esiRequired;
	@FXML
    private TextField pfNumber;
	@FXML
    private CheckBox pfRequired;
	@FXML
    private GridPane root;
	@FXML
    private CheckBox volContribotuin;
	@FXML
	private CustomTextField el;
	@FXML
	private CustomTextField cl;
	@FXML
	private CustomTextField sl;
	@FXML
	private TextField unitCode;
	@FXML
	private ChoiceBox<String> bankCode;
	@FXML
	private TextField accountNumber;
	@FXML
	CheckBox excludingBase;
	
	
	private Company currentcompany;
	private UserAccounts userAcounts;
	List<SalaryProfile> salaryProfilesList;
	SalaryStracture salaryStracture = null;
	SalaryProfile retrivedSalaryProfile = null;

	HashMap<String, String> totalCalMap= new HashMap<String, String> ();
	Employee employee = null;
	EmployeeDao employeeDao = PayrollApplicationFactory.getEmployeeMgmt();
	SalaryDAO salaryDAO = PayrollApplicationFactory.getSalaryDAO();
	
	public void goBack(ActionEvent event) {
		
		employee = null;
		salaryStracture = null;
		clearFields();
		if (getParent() != null && getParent().length() > 0) {
			PayrollApplicationFactory.getMainController().showScreen(
					getParent(), false);
		}
    
	}

	public void reset(ActionEvent event) {
		employee = null;
		salaryStracture = null;
		clearFields();
	}

	public void save() {

		String validationMsg = getValidationMessage();

		if (!validationMsg.equals("")) {
			showInfo(validationMsg);
			return;
		}
		
		SalaryStracture salaryStractureToUpdate = new SalaryStracture();
		salaryStractureToUpdate.setGrossSalary(grossSalary.getText());
		salaryStractureToUpdate.setBasic(basicPer.getText());
		salaryStractureToUpdate.setHra(hra.getText());
		salaryStractureToUpdate.setConveyance(conveyance.getText());
		salaryStractureToUpdate.setSpecialAllowance(specialAllowance.getText());
		salaryStractureToUpdate.setMedicalAllowance(medicalAllowance.getText());
		salaryStractureToUpdate.setOthers(others.getText());
		
		salaryStractureToUpdate.setPfrequired(pfRequired.isSelected());
		salaryStractureToUpdate.setVoluntary(volContribotuin.isSelected());
		salaryStractureToUpdate.setExcludingBase(excludingBase.isSelected());
		salaryStractureToUpdate.setEmployeeCont(employeeCont.getText());
		salaryStractureToUpdate.setEmployeerCont(emloyeerCont.getText());
		salaryStractureToUpdate.setPfNumber(pfNumber.getText());

		salaryStractureToUpdate.setEsirequired(esiRequired.isSelected());
		salaryStractureToUpdate.setEsiNumber(esiNumber.getText());
		salaryStractureToUpdate.setEl(el.getText());
		salaryStractureToUpdate.setCl(cl.getText());
		salaryStractureToUpdate.setSl(sl.getText());
		salaryStractureToUpdate.setEmployeeID(employee.getEmpId());
	
		salaryStractureToUpdate.setAccountNo(accountNumber.getText());
		salaryStractureToUpdate.setBankCode(bankCode.getSelectionModel().getSelectedItem());
		
		try {
			
			if(salaryStracture == null){

				salaryDAO.insertSalaryStracture(salaryStractureToUpdate);
			}else{

				salaryDAO.updateSalaryStracture(salaryStractureToUpdate);
			}
		} catch (BusinessException e) {
			e.printStackTrace();
			showError(e.getMessage());
		}
		
		showInfo("Successfully modified salary stracture for employee : "+employee.getEmpId());
	}

	@Override 
	public void initialize(URL fxmlFileLocation, ResourceBundle resources) {
		
		textFieldFocusHandler();
		
		
		pfRequired.selectedProperty().addListener(
				new ChangeListener<Boolean>() {
					public void changed(ObservableValue ov, Boolean old_val,
							Boolean new_val) {
						
						if(pfRequired.isSelected()){

							volContribotuin.setDisable(false);
							pfNumber.setDisable(false);
						}else{
							
							pfNumber.clear();
							pfNumber.setDisable(true);
							volContribotuin.setSelected(false);
							volContribotuin.setDisable(true);
						}
						
					}
				});
		

		volContribotuin.selectedProperty().addListener(
				new ChangeListener<Boolean>() {
					public void changed(ObservableValue ov, Boolean old_val,
							Boolean new_val) {
						
						if(volContribotuin.isSelected()){
							
							excludingBase.setDisable(false);
							emloyeerCont.setDisable(false);
							employeeCont.setDisable(false);
						}else{
							
							excludingBase.setSelected(false);
							emloyeerCont.clear();
							employeeCont.clear();
							
							excludingBase.setDisable(true);
							employeeCont.setDisable(true);
							emloyeerCont.setDisable(true);
						}
						
					}
				});
		
		esiRequired.selectedProperty().addListener(
				new ChangeListener<Boolean>() {
					public void changed(ObservableValue ov, Boolean old_val,
							Boolean new_val) {
						
						if(esiRequired.isSelected()){

							esiNumber.setDisable(false);
						}else{
							
							esiNumber.clear();
							esiNumber.setDisable(true);
						}
						
					}
				});
	}

	@Override
	public boolean isValid() {
		return false;
	}

	@Override
	public String getValidationMessage() {
		
		if(grossSalary.getText().trim().equals(""))
			return "Gross salary can not be empty";
		
		if(basicPer.getText().trim().equals(""))
			return "Basic percent can not be empty";
		if(hra.getText().trim().equals(""))
			return "HRA percent can not be empty";
		
		
		return "";
	
	}

	@Override
	public Parent getView() {
		return root;
	}

	@Override
	public String getTitle() {
		
		return "Salary Stracture";
	}

	@Override
	public void refreshUI(Object... args) {
		try {

			if (args != null && args.length > 0) {
				
				Company company = (Company) args[0];
				this.currentcompany = company;

				if(args.length > 1 && args[1] instanceof UserAccounts){
					
					userAcounts = (UserAccounts) args[1];
				}
				if(args.length > 2 && args[2] instanceof SalaryStracture){

					salaryStracture = (SalaryStracture) args[2];
					employee  = employeeDao.getEmpById(salaryStracture.getEmployeeID());

				}else{
					
					salaryStracture = null;
				}

				if(args.length > 2 && args[2] instanceof Employee){

					employee  = (Employee) args[2];
				}else {
					employee = null;
				}

				ArrayList<BankInfo> bankInfo = employeeDao.getBankInfo(null);
				ArrayList<String> bankCodeList = new ArrayList<String>();

				for(int i=0; i < bankInfo.size(); i++){

					bankCodeList.add(bankInfo.get(i).getBankCode());
				}

				bankCode.getItems().clear();
				bankCode.getItems().addAll(bankCodeList);
			}


		} catch (Exception e) {
			e.printStackTrace();
			showError(e.getMessage());
		}

		if(employee != null){

			empId.setText(employee.getEmpId());
			empName.setText(employee.getEmpName());
			company.setText(employee.getCompany().getCompanyID());
			departMent.setText(employee.getDepertment().getCode());
			unitCode.setText(employee.getUnit());
		}

		if(salaryStracture !=null){

			grossSalary.setText(salaryStracture.getGrossSalary());
			bankCode.getSelectionModel().select(salaryStracture.getBankCode());
			accountNumber.setText(salaryStracture.getAccountNo());
			basicPer.setText(salaryStracture.getBasic());
			hra.setText(salaryStracture.getHra());
			conveyance.setText(salaryStracture.getConveyance());
			specialAllowance.setText(salaryStracture.getSpecialAllowance());
			medicalAllowance.setText(salaryStracture.getMedicalAllowance());
			others.setText(salaryStracture.getOthers());

			pfRequired.setSelected(salaryStracture.isPfrequired());
			pfNumber.setText(salaryStracture.getPfNumber());
			excludingBase.setSelected(salaryStracture.isExcludingBase());
			volContribotuin.setSelected(salaryStracture.isVoluntary());
			employeeCont.setText(salaryStracture.getEmployeeCont());
			emloyeerCont.setText(salaryStracture.getEmployeerCont());
			esiRequired.setSelected(salaryStracture.isEsirequired());
			esiNumber.setText(salaryStracture.getEsiNumber());
			el.setText(salaryStracture.getEl());
			cl.setText(salaryStracture.getCl());
			sl.setText(salaryStracture.getSl());
		}


	}
	
	public void textFieldFocusHandler() {
		
		
		empId.focusedProperty().addListener(
				new ChangeListener<Boolean>() {
					@Override
					public void changed(ObservableValue<? extends Boolean> ov,
							Boolean lostFocus, Boolean getFocus) {
						PayRollUtility
						.debug("============== eidLableFocusHandler Start========================");
						if (lostFocus) {
							try {
								String employeeId = empId.getText().trim();
								if (!employeeId.equals("")) {
									PayRollUtility.validateEmpId(employeeId);
									employee = employeeDao.getEmpById(employeeId);
									empName.setText(employee.getEmpName());
									company.setText(employee.getCompany().getCompanyID());
									departMent.setText(employee.getDepertment().getCode());
									unitCode.setText(employee.getUnit());
									salaryStracture = salaryDAO.getSalaryStractureForEmp(employee.getEmpId());
									if(salaryStracture != null){
										refreshUI(currentcompany,userAcounts,salaryStracture);
									}else{
										refreshUI(currentcompany,userAcounts);
									}
								}
							} catch (Exception exception) {
								exception.printStackTrace();
								showError(exception.getMessage());
								refreshUI();
								moveFocusToComp(empId);
							}
						}
						PayRollUtility
						.debug("============== eidLableFocusHandler END========================");
					}
				});
		
		
	}
	
	private void clearFields(){
		
		empId.clear();
		grossSalary.clear();
		empName.clear();
		company.clear();
		departMent.clear();
		unitCode.clear();
		bankCode.getSelectionModel().clearSelection();
		basicPer.clear();
		hra.clear();
		conveyance.clear();
		specialAllowance.clear();
		medicalAllowance.clear();
		others.clear();
		pfRequired.setSelected(false);
		pfNumber.clear();
		volContribotuin.setSelected(false);
		excludingBase.setSelected(false);
		emloyeerCont.clear();
		employeeCont.clear();
		esiRequired.setSelected(false);
		esiNumber.clear();
		el.clear();
		cl.clear();
		sl.clear();
		accountNumber.clear();
	}
	
}
